using HtERP.Data;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Newtonsoft.Json;

namespace HtERP.Services
{
    /// <summary>
    /// 文件上传服务实现
    /// </summary>
    public class FileUploadService : IFileUploadService
    {
        private string _authToken = string.Empty;
        private DateTime? _authTokenExpiry;
        private const int DefaultTokenValidityMinutes = 30;
        private string _baseUrl;
        private readonly ILogger _logger;
        private readonly IConfiguration _configuration;
        private readonly IAuthService _authService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志服务</param>
        /// <param name="apiBaseUrl">API基础URL（从配置文件读取）</param>
        /// <param name="configuration">配置服务</param>
        /// <param name="authService">认证服务</param>
        public FileUploadService(ILogger logger, string apiBaseUrl = "https://localhost:5001/api", IConfiguration? configuration = null, IAuthService? authService = null)
        {
            _logger = logger;
            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _authService = authService ?? throw new ArgumentNullException(nameof(authService));
            
            // 优先使用配置文件中的ServerUrl设置
            var configServerUrl = _configuration["BackupPageSettings:ServerUrl"];
            if (!string.IsNullOrEmpty(configServerUrl))
            {
                _baseUrl = configServerUrl;
                _logger.Log(LogLevel.Info, $"FileUploadService: Using ServerUrl from configuration: {_baseUrl}");
            }
            else
            {
                _baseUrl = apiBaseUrl;
                _logger.Log(LogLevel.Info, $"FileUploadService: Using default API base URL: {_baseUrl}");
            }
        }

        /// <summary>
        /// 设置身份验证令牌
        /// </summary>
        public void SetAuthToken(string token)
        {
            _authToken = token;
            _authTokenExpiry = DateTime.Now.AddMinutes(DefaultTokenValidityMinutes);
            _logger.Log(LogLevel.Info, "Authentication token has been set successfully, valid until: " + _authTokenExpiry.Value.ToString("yyyy-MM-dd HH:mm:ss"));
        }

        /// <summary>
        /// 检查并刷新认证令牌（如果已过期或即将过期）
        /// </summary>
        /// <returns>有效的认证令牌</returns>
        public async Task<string> CheckAndRefreshAuthTokenAsync()
        {
            // 如果注入了认证服务，优先使用它获取令牌
            if (_authService != null)
            {
                _logger.Log(LogLevel.Info, "使用认证服务获取或刷新WebAPI认证令牌");
                _authToken = await _authService.GetOrRefreshAuthTokenAsync();
                if (!string.IsNullOrEmpty(_authToken))
                {
                    _authTokenExpiry = DateTime.Now.AddMinutes(DefaultTokenValidityMinutes);
                    _logger.Log(LogLevel.Info, "成功通过认证服务获取WebAPI认证令牌");
                    return _authToken;
                }
            }

            // 如果没有令牌或令牌已过期/即将在5分钟内过期，则使用内部方法刷新令牌
            bool needsRefresh = string.IsNullOrEmpty(_authToken) || 
                               !_authTokenExpiry.HasValue || 
                               DateTime.Now >= _authTokenExpiry.Value.AddMinutes(-5);
            
            if (needsRefresh)
            {
                _logger.Log(LogLevel.Info, "Authentication token needs to be refreshed or new token needs to be obtained");
                return await GetTemporaryAuthTokenAsync();
            }
            
            _logger.Log(LogLevel.Debug, "Authentication token is still valid, remaining validity: " + (_authTokenExpiry.HasValue ? _authTokenExpiry.Value.Subtract(DateTime.Now).TotalMinutes.ToString("F2") : "unknown") + " minutes");
            return _authToken;
        }

        /// <summary>
        /// 临时获取API服务器认证令牌
        /// </summary>
        private async Task<string> GetTemporaryAuthTokenAsync()
        {
            // 如果注入了认证服务，优先使用它获取令牌
            if (_authService != null)
            {
                _logger.Log(LogLevel.Info, "使用认证服务获取临时WebAPI认证令牌");
                _authToken = await _authService.GetOrRefreshAuthTokenAsync();
                if (!string.IsNullOrEmpty(_authToken))
                {
                    _authTokenExpiry = DateTime.Now.AddMinutes(DefaultTokenValidityMinutes);
                    _logger.Log(LogLevel.Info, "成功通过认证服务获取临时WebAPI认证令牌");
                    return _authToken;
                }
            }

            try
            {
                _logger.Log(LogLevel.Info, "尝试临时获取API服务器认证令牌");
                
                if (_configuration == null)
                {
                    _logger.Log(LogLevel.Warning, "配置服务未初始化，无法获取API认证凭据");
                    return string.Empty;
                }
                
                // 从配置中获取API认证凭据
                var apiUsername = _configuration["ApiSettings:ApiUsername"] ?? "aaa";
                var apiPassword = _configuration["ApiSettings:ApiPassword"] ?? "123456";
                
                if (string.IsNullOrEmpty(apiUsername) || string.IsNullOrEmpty(apiPassword))
                {
                    _logger.Log(LogLevel.Warning, "API认证凭据未配置");
                    return string.Empty;
                }
                
                // 创建HttpClientHandler并设置SSL证书验证回调
                var handler = new HttpClientHandler();
                
                // 检查配置是否忽略SSL证书错误
                bool ignoreSslErrors = false;
                if (_configuration != null)
                {
                    bool.TryParse(_configuration["ApiSettings:IgnoreSslCertificateErrors"], out ignoreSslErrors);
                }
                
                // 根据配置决定是否忽略SSL证书验证
                if (ignoreSslErrors || _baseUrl.StartsWith("https://localhost", StringComparison.OrdinalIgnoreCase))
                {
                    handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
                    _logger.Log(LogLevel.Info, "SSL certificate validation is disabled according to configuration");
                }
                
                using var httpClient = new HttpClient(handler);
                httpClient.DefaultRequestHeaders.Accept.Clear();
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                
                // 构建请求URL
                var baseUrl = _baseUrl.TrimEnd('/');
                var requestUrl = baseUrl.EndsWith("/api") ? $"{baseUrl}/Auth/login" : $"{baseUrl}/api/Auth/login";
                
                // 构建请求内容
                var loginRequest = new { Identifier = apiUsername, Password = apiPassword };
                var jsonContent = System.Text.Json.JsonSerializer.Serialize(loginRequest);
                var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
                
                // 发送请求
                var response = await httpClient.PostAsync(requestUrl, content);
                
                if (response.IsSuccessStatusCode)
                {
                    var responseContent = await response.Content.ReadAsStringAsync();
                    var result = JsonDocument.Parse(responseContent);
                    
                    // 从响应中获取令牌
                    if (result.RootElement.TryGetProperty("token", out var tokenElement))
                    {
                        var token = tokenElement.GetString();
                        if (!string.IsNullOrEmpty(token))
                        {
                            // 获取令牌有效期
                            int expiresIn = 30; // 默认30分钟
                            if (result.RootElement.TryGetProperty("expiresIn", out var expiresInElement))
                            {
                                expiresIn = expiresInElement.GetInt32();
                            }
                            
                            _authToken = token;
                            _authTokenExpiry = DateTime.Now.AddMinutes(expiresIn);
                            _logger.Log(LogLevel.Info, "成功获取临时API服务器认证令牌，有效期至: " + _authTokenExpiry.Value.ToString("yyyy-MM-dd HH:mm:ss"));
                        }
                        return token ?? string.Empty;
                    }
                    else
                    {
                        _logger.Log(LogLevel.Warning, "服务器响应中未包含token字段");
                        return string.Empty;
                    }
                }
                else
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    _logger.Log(LogLevel.Warning, $"临时获取API服务器认证令牌失败: {response.StatusCode}, {errorContent}");
                    return string.Empty;
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "获取临时API服务器认证令牌异常", ex);
                return string.Empty;
            }
        }

        /// <summary>
        /// 创建HttpClient
        /// </summary>
        /// <param name="authToken">可选的认证令牌</param>
        /// <param name="timeoutMinutes">超时时间（分钟），默认为5分钟</param>
        private HttpClient CreateHttpClient(string? authToken = null, int timeoutMinutes = 5)
        {
            _logger.Log(LogLevel.Info, $"Creating HttpClient for server: {_baseUrl}");
            
            // 创建HttpClientHandler来处理SSL证书验证
            var handler = new HttpClientHandler();
            
            // 检查配置是否忽略SSL证书错误
            bool ignoreSslErrors = false;
            if (_configuration != null)
            {
                bool.TryParse(_configuration["ApiSettings:IgnoreSslCertificateErrors"], out ignoreSslErrors);
            }
            
            // 根据配置决定是否忽略SSL证书验证
            if (ignoreSslErrors || _baseUrl.StartsWith("https://localhost", StringComparison.OrdinalIgnoreCase))
            {
                handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
                _logger.Log(LogLevel.Info, ignoreSslErrors ? "SSL certificate validation is disabled according to configuration" : "SSL certificate validation skipped for localhost");
            }
            
            var httpClient = new HttpClient(handler);
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            
            // 设置认证令牌（优先使用传入的令牌）
            var tokenToUse = authToken ?? _authToken;
            if (!string.IsNullOrEmpty(tokenToUse))
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenToUse);
                _logger.Log(LogLevel.Info, "Authorization header has been added to HttpClient");
            }
            else
            {
                _logger.Log(LogLevel.Warning, "No authentication token available when creating HttpClient");
            }
            
            // 设置超时时间
            httpClient.Timeout = TimeSpan.FromMinutes(timeoutMinutes);
            _logger.Log(LogLevel.Info, $"HttpClient timeout set to {timeoutMinutes} minutes");
            
            return httpClient;
        }

        /// <summary>
        /// 上传文件（根据文件大小自动选择上传方式）
        /// </summary>
        public async Task<UploadStatus> UploadFileAsync(string filePath, UploadRequest? request = null)
        {
            var status = new UploadStatus { FileId = string.Empty };

            try
            {
                _logger.Log(LogLevel.Info, "开始上传文件: " + filePath);
                if (!File.Exists(filePath))
                {
                    _logger.Log(LogLevel.Error, "文件不存在: " + filePath);
                    throw new FileNotFoundException("文件不存在", filePath);
                }

                var fileInfo = new FileInfo(filePath);
                status.TotalBytes = fileInfo.Length;
                
                _logger.Log(LogLevel.Info, "File info - Name: " + fileInfo.Name + ", Size: " + FormatFileSize(fileInfo.Length) + ", Path: " + fileInfo.FullName);
                
                // 确保request对象不为空且包含必要信息
                if (request == null)
                {
                    request = new UploadRequest();
                }
                
                if (string.IsNullOrEmpty(request.FileName))
                {
                    request.FileName = fileInfo.Name;
                }
                
                if (request.FileSize == 0)
                {
                    request.FileSize = fileInfo.Length;
                }
                
                if (string.IsNullOrEmpty(request.FileType))
                {
                    request.FileType = Path.GetExtension(fileInfo.Name).TrimStart('.');
                }
                
                // 调用分块上传方法来执行实际的文件上传
                var chunkStatus = await UploadFileInChunksAsync(filePath, request);
                
                // 将分块上传的状态复制到当前状态
                status.FileId = chunkStatus.FileId;
                status.Completed = chunkStatus.Completed;
                status.UploadedBytes = chunkStatus.UploadedBytes;
                status.TotalBytes = chunkStatus.TotalBytes;
                status.ErrorMessage = chunkStatus.ErrorMessage;
                
                // chunkStatus已经包含了错误信息，不需要再次设置
                // if (!status.Completed && !string.IsNullOrEmpty(chunkStatus.ErrorMessage))
                // {
                //     status.ErrorMessage = chunkStatus.ErrorMessage;
                // }
                
                _logger.Log(LogLevel.Info, "文件上传完成，状态: " + (status.Completed ? "成功" : "失败") + ", 文件ID: " + status.FileId);
                return status;
            }
            catch (FileNotFoundException ex)
            {
                _logger.Log(LogLevel.Error, "文件不存在: " + ex.FileName, ex);
                status.Completed = false;
                status.ErrorMessage = ex.Message;
                return status;
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "文件上传过程中发生错误: " + ex.Message, ex);
                _logger.Log(LogLevel.Error, "异常详情: " + ex.StackTrace, ex);
                
                if (ex.InnerException != null)
                {
                    _logger.Log(LogLevel.Error, "内部异常: " + ex.InnerException.Message, ex.InnerException);
                }
                
                status.Completed = false;
                status.ErrorMessage = ex.Message;
                return status;
            }
        }

        /// <summary>
        /// 使用分块方式上传大文件
        /// </summary>
        public async Task<UploadStatus> UploadFileInChunksAsync(string filePath, UploadRequest request, long chunkSize = 4 * 1024 * 1024)
        {            
            var status = new UploadStatus();            
            CancellationTokenSource? cancellationTokenSource = null;            
            string uploadSessionId = string.Empty;            
            
            // 获取API服务器认证令牌，优先使用认证服务提供的令牌
            string tempAuthToken = await CheckAndRefreshAuthTokenAsync();
            if (string.IsNullOrEmpty(tempAuthToken))
            {
                _logger.Log(LogLevel.Error, "无法获取API服务器认证令牌，上传失败");
                status.Completed = false;
                status.ErrorMessage = "无法获取认证令牌";
                return status;
            }

            try
            {
                var fileInfo = new FileInfo(filePath);
                if (!fileInfo.Exists)
                {
                    _logger.Log(LogLevel.Error, "文件不存在: " + filePath);
                    status.Completed = false;
                    status.ErrorMessage = "文件不存在";
                    return status;
                }

                _logger.Log(LogLevel.Info, "File info - Name: " + fileInfo.Name + ", Size: " + FormatFileSize(fileInfo.Length) + ", Path: " + fileInfo.FullName);

                // 确保request对象不为空且包含必要信息
                if (request == null)
                {
                    request = new UploadRequest();
                }

                if (string.IsNullOrEmpty(request.FileName))
                {
                    request.FileName = fileInfo.Name;
                }

                if (request.FileSize == 0)
                {
                    request.FileSize = fileInfo.Length;
                }

                if (string.IsNullOrEmpty(request.FileType))
                {
                    request.FileType = Path.GetExtension(fileInfo.Name).TrimStart('.');
                }

                // 创建上传会话，添加重试逻辑
                int maxRetries = 3;

                // 使用for循环替代while循环，与DbBackupTool保持一致
                for (int retry = 0; retry < maxRetries; retry++)
                {
                    try
                    {
                        uploadSessionId = await CreateUploadSessionAsync(fileInfo, request, tempAuthToken);
                        if (!string.IsNullOrEmpty(uploadSessionId))
                        {
                            _logger.Log(LogLevel.Info, "成功创建上传会话: " + uploadSessionId);
                            break;
                        }
                        throw new Exception("Failed to create upload session");
                    }
                    catch (Exception ex)
                    {
                        _logger.Log(LogLevel.Error, "创建上传会话失败 (尝试 " + (retry + 1) + "/" + maxRetries + "): " + ex.Message, ex);
                        _logger.Log(LogLevel.Error, "异常详情: " + ex.StackTrace, ex);

                        if (ex.InnerException != null)
                        {
                            _logger.Log(LogLevel.Error, "内部异常: " + ex.InnerException.Message, ex);
                        }

                        if (retry >= maxRetries - 1)
                        {
                            status.Completed = false;
                            status.ErrorMessage = $"创建上传会话失败: {ex.Message}";
                            return status;
                        }

                        // 等待一段时间后重试，与DbBackupTool保持一致的重试间隔计算
                        int delay = 2000 * (retry + 1);
                        _logger.Log(LogLevel.Info, "等待 " + delay + "ms 后重试");
                        await Task.Delay(delay);
                    }
                }

                status.FileId = uploadSessionId;

                // 创建取消令牌
                cancellationTokenSource = new CancellationTokenSource();

                using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, (int)chunkSize, FileOptions.Asynchronous))
                {
                    long fileSize = fileStream.Length;
                    long uploadedBytes = 0;
                    int chunkIndex = 0;
                    int totalChunks = (int)Math.Ceiling((double)fileSize / chunkSize);

                    // 上传所有块
                    while (uploadedBytes < fileSize)
                    {
                        // 检查是否取消上传
                        if (cancellationTokenSource.Token.IsCancellationRequested)
                        {
                            _logger.Log(LogLevel.Warning, "上传被取消: " + filePath);
                            try
                            {
                                if (uploadSessionId != null)
                                {
                                    await CancelUploadSessionAsync(uploadSessionId, tempAuthToken);
                                }
                            }
                            catch (Exception cancelEx)
                            {
                                _logger.Log(LogLevel.Warning, "取消上传会话失败: " + cancelEx.Message);
                            }
                            status.Completed = false;
                            status.ErrorMessage = "上传已取消";
                            return status;
                        }

                        // 读取块数据
                        byte[] buffer = new byte[chunkSize];
                        int bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);

                        // 上传块，添加重试逻辑
                        bool chunkUploaded = false;

                        // 使用for循环替代while循环，与DbBackupTool保持一致
                        for (int retry = 0; retry < maxRetries; retry++)
                        {
                            try
                            {
                                if (uploadSessionId != null)
                                {
                                    await UploadChunkAsync(uploadSessionId, buffer, bytesRead, chunkIndex, totalChunks, chunkSize, fileSize, fileInfo.Name, tempAuthToken);
                                }
                                else
                                {
                                    throw new InvalidOperationException("上传会话ID为空，无法继续上传");
                                }
                                chunkUploaded = true;
                                _logger.Log(LogLevel.Info, "文件块 " + (chunkIndex + 1) + "/" + totalChunks + " 上传成功");
                                break;
                            }
                            catch (Exception ex)
                            {
                                _logger.Log(LogLevel.Error, "上传文件块 " + (chunkIndex + 1) + " 失败 (尝试 " + (retry + 1) + "/" + maxRetries + "): " + ex.Message, ex);
                                _logger.Log(LogLevel.Error, "异常详情: " + ex.StackTrace, ex);

                                if (ex.InnerException != null)
                                {
                                    _logger.Log(LogLevel.Error, "内部异常: " + ex.InnerException.Message, ex);
                                }

                                if (retry >= maxRetries - 1)
                                {
                                    try
                                    {
                                        if (uploadSessionId != null)
                                        {
                                            await CancelUploadSessionAsync(uploadSessionId, tempAuthToken);
                                        }
                                    }
                                    catch { }

                                    status.Completed = false;
                                    status.ErrorMessage = ex.Message;
                                    return status;
                                }

                                // 等待一段时间后重试，与DbBackupTool保持一致的重试间隔计算
                                int delay = 2000 * (retry + 1);
                                _logger.Log(LogLevel.Info, "等待 " + delay + "ms 后重试");
                                await Task.Delay(delay);
                            }
                        }

                        if (chunkUploaded)
                        {
                            uploadedBytes += bytesRead;
                            chunkIndex++;
                            status.UploadedBytes = uploadedBytes;

                            // 记录上传进度
                            double progress = (double)uploadedBytes / fileSize * 100;
                            _logger.Log(LogLevel.Info, "文件上传进度: " + progress.ToString("F2") + "% (" + FormatFileSize(uploadedBytes) + "/" + FormatFileSize(fileSize) + ")");
                        }
                    }

                    // 完成上传会话，添加重试逻辑
                    FileUploadResponse? finalResponse = null;

                    // 使用for循环替代while循环，与DbBackupTool保持一致
                    for (int retry = 0; retry < maxRetries; retry++)
                        {
                            try
                            {
                                if (uploadSessionId != null)
                                {
                                    finalResponse = await CompleteUploadSessionAsync(uploadSessionId, tempAuthToken);
                                }
                                else
                                {
                                    throw new InvalidOperationException("上传会话ID为空，无法完成上传");
                                }
                            {
                                _logger.Log(LogLevel.Info, "上传会话完成成功");
                                break;
                            }
                            throw new Exception(finalResponse?.ErrorMessage ?? "Failed to complete upload session");
                        }
                        catch (Exception ex)
                        {
                            _logger.Log(LogLevel.Error, "完成上传会话失败 (尝试 " + (retry + 1) + "/" + maxRetries + "): " + ex.Message, ex);
                            _logger.Log(LogLevel.Error, "异常详情: " + ex.StackTrace, ex);

                            if (retry >= maxRetries - 1)
                            {
                                status.Completed = false;
                                status.ErrorMessage = ex.Message;
                                return status;
                            }

                            // 等待一段时间后重试，与DbBackupTool保持一致的重试间隔计算
                            int delay = 2000 * (retry + 1);
                            _logger.Log(LogLevel.Info, "等待 " + delay + "ms 后重试");
                            await Task.Delay(delay);
                        }
                    }

                    status.Completed = true;
                    status.FileId = finalResponse != null ? finalResponse.Id.ToString() : uploadSessionId;
                    _logger.Log(LogLevel.Info, "分块上传成功完成: " + filePath);

                    return status;
                }
            }
            catch (OperationCanceledException)
            {
                _logger.Log(LogLevel.Warning, "上传操作被取消: " + filePath);

                // 尝试取消上传会话
                if (!string.IsNullOrEmpty(uploadSessionId))
                {
                    try
                    {
                        await CancelUploadSessionAsync(uploadSessionId, tempAuthToken);
                    }
                    catch (Exception cancelEx)
                    {
                        _logger.Log(LogLevel.Warning, "取消上传会话失败: " + cancelEx.Message, cancelEx);
                    }
                }

                status.Completed = false;
                status.ErrorMessage = "上传已取消";
                return status;
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "分块文件上传过程中发生错误: " + ex.Message, ex);
                _logger.Log(LogLevel.Error, "异常详情: " + ex.StackTrace, ex);

                if (ex.InnerException != null)
                {
                    _logger.Log(LogLevel.Error, "内部异常: " + ex.InnerException.Message, ex.InnerException);
                }

                // 尝试取消上传会话
                if (!string.IsNullOrEmpty(uploadSessionId))
                {
                    try
                    {
                        await CancelUploadSessionAsync(uploadSessionId, tempAuthToken);
                    }
                    catch (Exception cancelEx)
                    {
                        _logger.Log(LogLevel.Warning, "取消上传会话失败: " + cancelEx.Message, cancelEx);
                    }
                }

                status.Completed = false;
                status.ErrorMessage = ex.Message;
                return status;
            }
            finally
            {
                // 释放取消令牌源
                cancellationTokenSource?.Dispose();
            }
        }

        /// <summary>
        /// 取消上传
        /// </summary>
        public void CancelUpload(string fileId)
        {
            try
            {
                _logger.Log(LogLevel.Info, "Cancel upload requested for fileId: " + fileId);
                // 异步执行取消操作但不等待结果
                _ = CancelUploadSessionAsync(fileId);
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "Error canceling upload: " + ex.Message, ex);
            }
        }
        
        /// <summary>
        /// 使用指定的认证令牌取消上传
        /// </summary>
        public void CancelUpload(string fileId, string authToken)
        {
            try
            {
                _logger.Log(LogLevel.Info, "Cancel upload requested for fileId: " + fileId + " with auth token");
                // 异步执行取消操作但不等待结果
                _ = CancelUploadSessionAsync(fileId, authToken);
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "Error canceling upload with auth token: " + ex.Message, ex);
            }
        }

        /// <summary>
        /// 检查服务器连接
        /// </summary>
        public async Task<bool> CheckServerConnectionAsync()
        {
            try
            {
                _logger.Log(LogLevel.Info, "Checking server connection: " + _baseUrl);
                
                using (var httpClient = CreateHttpClient())
                {
                    var pingUrl = $"{_baseUrl}/Test/ping";
                    var response = await httpClient.GetAsync(pingUrl);
                    
                    bool success = response.IsSuccessStatusCode;
                    _logger.Log(LogLevel.Info, "Server connection check result: " + (success ? "Successful" : "Failed"));
                    
                    return success;
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "Server connection check failed: " + ex.Message, ex);
                return false;
            }
        }

        /// <summary>
        /// 创建上传会话
        /// </summary>
        private async Task<string> CreateUploadSessionAsync(FileInfo fileInfo, UploadRequest? request, string? authToken = null)
        {
            try
            {
                // 创建上传会话请求对象，确保与DbBackupTool保持一致
                var sessionRequest = new 
                {
                    FileName = fileInfo.Name,
                    FileSize = fileInfo.Length,
                    Metadata = request
                };

                var jsonContent = JsonConvert.SerializeObject(sessionRequest);
                var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

                using (var httpClient = CreateHttpClient(authToken))
                {
                    // 修复URL构建，确保不重复添加api路径，与DbBackupTool保持一致
                    var baseUrl = _baseUrl.TrimEnd('/');
                    var requestUrl = baseUrl.EndsWith("/api") 
                        ? $"{baseUrl}/File/upload/session" 
                        : $"{baseUrl}/api/File/upload/session";
                    
                    _logger.Log(LogLevel.Info, "创建上传会话: " + requestUrl);
                    
                    try
                    {
                        var response = await httpClient.PostAsync(requestUrl, content);
                        
                        // 处理认证失败的情况
                        if ((int)response.StatusCode == 401 && authToken == null)
                        {
                            _logger.Log(LogLevel.Info, "认证令牌过期或无效，尝试重新获取...");
                            authToken = await GetTemporaryAuthTokenAsync();
                            return await CreateUploadSessionAsync(fileInfo, request, authToken);
                        }
                        
                        // 检查响应状态
                        if (!response.IsSuccessStatusCode)
                        {
                            var errorContent = await response.Content.ReadAsStringAsync();
                            _logger.Log(LogLevel.Error, "创建上传会话失败: HTTP " + (int)response.StatusCode + " - " + errorContent);
                            throw new Exception($"创建上传会话失败: HTTP {(int)response.StatusCode} - {errorContent}");
                        }

                        var responseContent = await response.Content.ReadAsStringAsync();
                        _logger.Log(LogLevel.Debug, "会话创建响应: " + responseContent);
                        
                        // 改进JSON解析，捕获可能的解析异常
                        dynamic? result = null;
                        try
                        {
                            result = JsonConvert.DeserializeObject<dynamic>(responseContent);
                        }
                        catch (Newtonsoft.Json.JsonException jsonEx)
                        {
                            _logger.Log(LogLevel.Error, "解析上传会话响应失败: " + jsonEx.Message, jsonEx);
                            _logger.Log(LogLevel.Error, "原始响应内容: " + responseContent, jsonEx);
                            throw new Exception("解析上传会话响应失败", jsonEx);
                        }
                        
                        if (result == null)
                        {
                            _logger.Log(LogLevel.Error, "Failed to parse session creation response");
                            throw new Exception("创建上传会话失败: 响应解析失败");
                        }
                        
                        // 安全地访问uploadId属性
                        string uploadId = result?.uploadId?.ToString() ?? string.Empty;
                        if (string.IsNullOrEmpty(uploadId))
                        {
                            _logger.Log(LogLevel.Error, "Failed to get UploadId from session creation response");
                            throw new Exception("创建上传会话失败: 未返回有效的UploadId");
                        }
                        
                        _logger.Log(LogLevel.Info, "成功创建上传会话: " + uploadId);
                        return uploadId;
                    }
                    catch (HttpRequestException ex)
                    {
                        _logger.Log(LogLevel.Error, "创建上传会话网络异常: " + (ex.StatusCode.HasValue ? (int)ex.StatusCode.Value : 0) + " - " + ex.Message, ex);
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "创建上传会话异常: " + ex.Message, ex);
                _logger.Log(LogLevel.Error, "异常堆栈: " + ex.StackTrace, ex);
                
                if (ex.InnerException != null)
                {
                    _logger.Log(LogLevel.Error, "内部异常: " + ex.InnerException.Message, ex.InnerException);
                }
                
                throw;
            }
        }

        /// <summary>
        /// 上传文件块
        /// </summary>
        private async Task UploadChunkAsync(string sessionId, byte[] buffer, int bytesRead, int chunkIndex, int totalChunks, long chunkSize, long totalSize, string fileName, string? authToken = null)
        {
            int maxRetries = 3;
            bool tokenRefreshed = false;
            
            for (int retry = 0; retry <= maxRetries; retry++)
            {
                try
                {
                    using (var content = new MultipartFormDataContent())
                    {
                        // 添加所有必需的参数，确保与服务端的FileChunkRequest模型匹配
                        content.Add(new StringContent(sessionId), "UploadId");
                        // 修复：WebApi要求ChunkNumber从1开始，所以需要+1
                        content.Add(new StringContent((chunkIndex + 1).ToString()), "ChunkNumber");
                        content.Add(new StringContent(totalChunks.ToString()), "TotalChunks");
                        content.Add(new StringContent(chunkSize.ToString(System.Globalization.CultureInfo.InvariantCulture)), "ChunkSize");
                        content.Add(new StringContent(totalSize.ToString(System.Globalization.CultureInfo.InvariantCulture)), "TotalSize");
                        content.Add(new StringContent(fileName), "FileName");
                        
                        // 优化流处理，使用MemoryStream包装buffer
                        using (var ms = new MemoryStream(buffer, 0, bytesRead))
                        {
                            var streamContent = new StreamContent(ms);
                            streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                            // 使用大写File字段名，与服务端保持一致
                            content.Add(streamContent, "File", $"chunk_{chunkIndex}");

                            using (var httpClient = CreateHttpClient(authToken))
                            {
                                _logger.Log(LogLevel.Info, "正在上传文件块 " + (chunkIndex + 1) + "/" + totalChunks + (retry > 0 ? " (重试 " + retry + "/" + maxRetries + ")" : ""));
                                _logger.Log(LogLevel.Info, "文件块大小: " + FormatFileSize(bytesRead));
                                
                                // 修复URL构建，使用大写File以匹配控制器名
                                var baseUrl = _baseUrl.TrimEnd('/');
                                if (baseUrl.EndsWith("/api"))
                                {
                                    baseUrl = baseUrl.Substring(0, baseUrl.Length - 4);
                                }
                                var uploadUrl = $"{baseUrl}/api/File/upload/chunk";
                                _logger.Log(LogLevel.Info, "上传URL: " + uploadUrl);
                                
                                var response = await httpClient.PostAsync(uploadUrl, content);
                                
                                if (response.IsSuccessStatusCode)
                                {
                                    _logger.Log(LogLevel.Info, "文件块 " + (chunkIndex + 1) + " 上传成功，状态码: " + (int)response.StatusCode);
                                    break; // 上传成功，跳出重试循环
                                }
                                else
                                {
                                    var errorContent = await response.Content.ReadAsStringAsync();
                                    _logger.Log(LogLevel.Error, "文件块 " + (chunkIndex + 1) + " 上传失败: HTTP " + (int)response.StatusCode + " - " + errorContent);
                                    
                                    // 处理认证失败的情况
                                    if ((int)response.StatusCode == 401 && !tokenRefreshed)
                                    {
                                        _logger.Log(LogLevel.Info, "认证令牌过期或无效，尝试重新获取...");
                                        authToken = await GetTemporaryAuthTokenAsync();
                                        tokenRefreshed = true;
                                        // 继续下一次循环重试，但不计入重试次数
                                        retry--;
                                        continue;
                                    }
                                    
                                    if (retry >= maxRetries)
                                    {
                                        throw new Exception($"上传文件块 {chunkIndex + 1} 失败，已达到最大重试次数");
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Log(LogLevel.Error, "上传文件块 " + (chunkIndex + 1) + " 失败: " + ex.Message, ex);
                    _logger.Log(LogLevel.Error, "异常详情: " + ex.StackTrace, ex);
                    
                    if (ex.InnerException != null)
                    {
                        _logger.Log(LogLevel.Error, "内部异常: " + ex.InnerException.Message, ex.InnerException);
                    }
                    
                    if (retry >= maxRetries)
                    {
                        throw new Exception($"上传文件块 {chunkIndex + 1} 失败，已达到最大重试次数", ex);
                    }
                }
                
                // 等待一段时间后重试
                _logger.Log(LogLevel.Info, "等待 " + 2000 * (retry + 1) + "ms 后重试，当前重试次数: " + (retry + 1) + "/" + maxRetries);
                await Task.Delay(2000 * (retry + 1));
            }
        }

        /// <summary>
        /// 完成上传会话
        /// </summary>
        private async Task<FileUploadResponse> CompleteUploadSessionAsync(string sessionId, BackupSchedule schedule)
        {
            try
            {
                using (var httpClient = CreateHttpClient(schedule))
                {
                    // 修复URL构建，确保不重复添加api路径，使用大写File
                    var baseUrl = schedule.ServerUrl.TrimEnd('/');
                    if (baseUrl.EndsWith("/api"))
                    {
                        baseUrl = baseUrl.Substring(0, baseUrl.Length - 4);
                    }
                    var completeUrl = $"{baseUrl}/api/File/upload/complete";

                    var content = new StringContent(JsonConvert.SerializeObject(new { UploadId = sessionId }));
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    var response = await httpClient.PostAsync(completeUrl, content);
                    response.EnsureSuccessStatusCode();

                    var responseContent = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<FileUploadResponse>(responseContent);
                    if (result == null)
                    {
                        _logger.Log(LogLevel.Error, "上传响应反序列化返回null，创建默认响应对象");
                        result = new FileUploadResponse { Success = false, ErrorMessage = "无法解析服务器响应" };
                    }
                    return result;
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, $"完成上传会话失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 完成上传会话（重载方法）
        /// </summary>
        private async Task<FileUploadResponse> CompleteUploadSessionAsync(string sessionId, string authToken)
        {
            try
            {
                using (var httpClient = CreateHttpClient(authToken))
                {
                    // 修复URL构建，确保不重复添加api路径，使用大写File
                    var baseUrl = _baseUrl.TrimEnd('/');
                    if (baseUrl.EndsWith("/api"))
                    {
                        baseUrl = baseUrl.Substring(0, baseUrl.Length - 4);
                    }
                    var completeUrl = $"{baseUrl}/api/File/upload/complete";

                    var content = new StringContent(JsonConvert.SerializeObject(new { UploadId = sessionId }));
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    var response = await httpClient.PostAsync(completeUrl, content);
                    response.EnsureSuccessStatusCode();

                    var responseContent = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<FileUploadResponse>(responseContent);
                    if (result == null)
                    {
                        _logger.Log(LogLevel.Error, "上传响应反序列化返回null，创建默认响应对象");
                        result = new FileUploadResponse { Success = false, ErrorMessage = "无法解析服务器响应" };
                    }
                    return result;
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, $"完成上传会话失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 取消上传会话
        /// </summary>
        private async Task CancelUploadSessionAsync(string sessionId)
        {
            try
            {
                _logger.Log(LogLevel.Info, "取消上传会话，会话ID: " + sessionId);
                // 使用默认认证令牌取消上传
                await CancelUploadSessionAsync(sessionId, _authToken);
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "取消上传会话过程中发生异常: " + ex.Message);
            }
        }

        /// <summary>
        /// 取消上传会话
        /// </summary>
        private async Task CancelUploadSessionAsync(string sessionId, string authToken)
        {
            try
            {
                using (var httpClient = CreateHttpClient(authToken))
                {
                    // 修复URL构建，确保不重复添加api路径，使用大写File
                    var baseUrl = _baseUrl.TrimEnd('/');
                    if (baseUrl.EndsWith("/api"))
                    {
                        baseUrl = baseUrl.Substring(0, baseUrl.Length - 4);
                    }
                    var cancelUrl = $"{baseUrl}/api/File/upload/cancel";

                    var content = new StringContent(JsonConvert.SerializeObject(new { UploadId = sessionId }));
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    try
                    {
                        var response = await httpClient.PostAsync(cancelUrl, content);
                        response.EnsureSuccessStatusCode();

                        _logger.Log(LogLevel.Info, $"上传会话已取消，会话ID: {sessionId}");
                    }
                    catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.MethodNotAllowed)
                    {
                        // WebApi中没有实现取消上传的端点，记录警告日志但不抛出异常
                        _logger.Log(LogLevel.Warning, $"取消上传会话时遇到405错误，服务端可能未实现此功能: {ex.Message}");
                    }
                    catch (Exception ex)
                    {
                        _logger.Log(LogLevel.Error, $"取消上传会话失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, $"取消上传会话过程中发生异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 取消上传会话
        /// </summary>
        private async Task CancelUploadSessionAsync(string sessionId, BackupSchedule schedule)
        {
            try
            {
                using (var httpClient = CreateHttpClient(schedule))
                {
                    // 修复URL构建，确保不重复添加api路径，使用大写File
                    var baseUrl = schedule.ServerUrl.TrimEnd('/');
                    if (baseUrl.EndsWith("/api"))
                    {
                        baseUrl = baseUrl.Substring(0, baseUrl.Length - 4);
                    }
                    var cancelUrl = $"{baseUrl}/api/File/upload/cancel";

                    var content = new StringContent(JsonConvert.SerializeObject(new { UploadId = sessionId }));
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    try
                    {
                        var response = await httpClient.PostAsync(cancelUrl, content);
                        response.EnsureSuccessStatusCode();

                        _logger.Log(LogLevel.Info, $"上传会话已取消，会话ID: {sessionId}");
                    }
                    catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.MethodNotAllowed)
                    {
                        // WebApi中没有实现取消上传的端点，记录警告日志但不抛出异常
                        _logger.Log(LogLevel.Warning, $"取消上传会话时遇到405错误，服务端可能未实现此功能: {ex.Message}");
                    }
                    catch (Exception ex)
                    {
                        _logger.Log(LogLevel.Error, $"取消上传会话失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, $"取消上传会话过程中发生异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 格式化文件大小为可读字符串
        /// </summary>
        private string FormatFileSize(long bytes)
        {
            string[] suffix = { "B", "KB", "MB", "GB", "TB" };
            int i = 0;
            double dblBytes = bytes;

            if (bytes > 0)
            {
                while (dblBytes >= 1024 && i < suffix.Length - 1)
                {
                    dblBytes /= 1024;
                    i++;
                }
            }

            return $"{dblBytes:F2} {suffix[i]}";
        }

        /// <summary>
        /// 根据备份计划创建HttpClient
        /// </summary>
        private HttpClient CreateHttpClient(BackupSchedule schedule)
        {
            _logger.Log(LogLevel.Info, $"Creating HttpClient for server: {schedule.ServerUrl}");

            // 创建HttpClientHandler来处理SSL证书验证
            var handler = new HttpClientHandler();

            // 对于localhost环境，忽略SSL证书验证
            if (schedule.ServerUrl.StartsWith("https://localhost", StringComparison.OrdinalIgnoreCase))
            {
                handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
                _logger.Log(LogLevel.Info, "SSL certificate validation skipped for localhost");
            }

            var httpClient = new HttpClient(handler);
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // 设置认证令牌
            if (!string.IsNullOrEmpty(_authToken))
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _authToken);
                _logger.Log(LogLevel.Info, "Authorization header has been added to HttpClient");
            }
            else
            {
                _logger.Log(LogLevel.Warning, "No authentication token available when creating HttpClient");
            }

            // 设置超时时间
            int timeoutMinutes = schedule.UploadTimeout > 0 ? (int)(schedule.UploadTimeout / 60000) : 10;
            httpClient.Timeout = TimeSpan.FromMinutes(timeoutMinutes);
            _logger.Log(LogLevel.Info, $"HttpClient timeout set to {timeoutMinutes} minutes");

            return httpClient;
        }

    }



}